using System;
using System.Windows.Forms;
using System.Drawing;
using System.ComponentModel;
using System.Collections;
using System.Diagnostics;

namespace ADN.Windows.Ctrl
{
	/// <summary>
	/// Implementation of a DateTimePicker as a column in a DataGrid
	/// </summary>
	public class DataGriDateTimePicker : DataGridColumnStyle 
	{
		private int			_xMargin		=	2;
		private int			_yMargin		=	1;
		private	DateTimePicker	_dateTimePicker;
		private bool		_inEdit			=	false;
		private DataGrid	_dataGrid;
		
		public new bool ReadOnly   // Hide base member ReadOnly.
		{
			get
			{
				if ( _dataGrid != null )
					return _dataGrid.ReadOnly;
				return true;
			}
		}

		/// <summary>
		/// The only creator ;)
		/// </summary>
		/// <param name="colName">The name of the column</param>
		/// <param name="dataSource">The datasource that contains the lookup table</param>
		/// <param name="displayMember">The member of the lookuptable to display</param>
		/// <param name="valueMember">The member of the lookuptable with the value</param>
		/// <param name="dataGrid">The datagrid parent of this column</param>

		public DataGriDateTimePicker(string HeaderTxt, string colName, DataGrid dataGrid) 
		{
			_dateTimePicker				=	new DateTimePicker();
			_dateTimePicker.Visible		=	false;
			_dataGrid				=	dataGrid;
			this.MappingName		=	colName;
			this.HeaderText			=	HeaderTxt;
			dataGrid.Controls.Add(_dateTimePicker);
		}

		/// <summary>
		/// Standard override
		/// </summary>
		/// <param name="rowNum"></param>
		protected override void Abort(int rowNum) 
		{
			_inEdit	=	false;
			if ( _dateTimePicker != null && _dateTimePicker.Visible	)
				_dateTimePicker.Hide();
		}
		/// <summary>
		/// Standard override
		/// </summary>
		/// <param name="dataSource"></param>
		/// <param name="rowNum"></param>
		/// <returns></returns>
		protected override bool Commit(CurrencyManager dataSource,int rowNum) 
		{
			if ( !_inEdit || _dateTimePicker == null ) 
				return true;
			try 
			{
				DateTime val1		= _dateTimePicker.Value;
				object	val2		=	GetColumnValueAtRow(dataSource, rowNum);
				if ( val2 is DateTime )
				{
					if ( val1 == (DateTime)val2 )
						return true;

				}
				else if ( GetText(val1) == GetText(val2) )
					return true;
				
				this.SetColumnValueAtRow(dataSource, rowNum, val1);
			}
			catch 
			{
				return false;
			}
			finally 
			{
				_inEdit	=	false;
				_dateTimePicker.Hide();
			}
			return true;
		}
		
		/// <summary>
		/// Standard override
		/// </summary>
		/// <param name="source"></param>
		/// <param name="rowNum"></param>
		/// <param name="bounds"></param>
		/// <param name="readOnly"></param>
		/// <param name="instantText"></param>
		/// <param name="cellIsVisible"></param>
		protected override void Edit(CurrencyManager source, int rowNum, Rectangle bounds, bool readOnly, string instantText, bool cellIsVisible) 
		{
			if ( _dateTimePicker == null )
				return;
			if ( ReadOnly )
				return;
			if(	!cellIsVisible ) 
				return;
			try
			{
				Rectangle originalBounds		=	bounds;
				originalBounds.Offset(_xMargin, _yMargin);
				originalBounds.Width			-=	_xMargin * 2;
				originalBounds.Height			-=	_yMargin;
				_dateTimePicker.Bounds			=	originalBounds;
				_dateTimePicker.Visible			=	true;
				_inEdit							=	true;
			
				if( instantText != null ) 
				{
					_dateTimePicker.Value		=	Convert.ToDateTime(instantText);
				} 
				else 
				{
					object	val2				=	GetColumnValueAtRow(source, rowNum);
					if ( val2 is DateTime )
							_dateTimePicker.Value		=	(DateTime)val2;
					else	_dateTimePicker.Value		=	Convert.ToDateTime(val2);
				}

			}
			catch
			{}
		}
		
		/// <summary>
		/// Standard override
		/// </summary>
		/// <returns></returns>
		protected override int GetMinimumHeight() 
		{
			return _dateTimePicker.PreferredHeight + _yMargin;
		}
		
		/// <summary>
		/// Standard override
		/// </summary>
		/// <param name="g"></param>
		/// <param name="val"></param>
		/// <returns></returns>
		protected override int GetPreferredHeight(Graphics g ,object val) 
		{
			return FontHeight + _yMargin;
		}
		
		/// <summary>
		/// Standard override
		/// </summary>
		/// <param name="g"></param>
		/// <param name="val"></param>
		/// <returns></returns>
		protected override Size GetPreferredSize(Graphics g, object val) 
		{
			Size _extents	=	Size.Ceiling(g.MeasureString(GetText(val), this.DataGridTableStyle.DataGrid.Font));
			_extents.Width	+=	_xMargin * 2 ;
			_extents.Height +=	_yMargin;
			return _extents;
		}
		
		/// <summary>
		/// Standard override
		/// </summary>
		/// <param name="g"></param>
		/// <param name="bounds"></param>
		/// <param name="source"></param>
		/// <param name="rowNum"></param>
		protected override void Paint(Graphics g,Rectangle bounds,CurrencyManager source,int rowNum) 
		{
			Paint(g, bounds, source, rowNum, false);
		}

		/// <summary>
		/// Standard override
		/// </summary>
		/// <param name="g"></param>
		/// <param name="bounds"></param>
		/// <param name="source"></param>
		/// <param name="rowNum"></param>
		/// <param name="alignToRight"></param>
		protected override void Paint(Graphics g,Rectangle bounds,CurrencyManager source,int rowNum, bool alignToRight) 
		{
			bool	selectedRow	=	false;
			bool	dgSelectedRow	=	false;
			try
			{
				if ( source.Position == rowNum )
					selectedRow	=	true;
				if ( _dataGrid.IsSelected(rowNum) )
					dgSelectedRow	=	true;
				object	val2	=	GetColumnValueAtRow(source, rowNum);
				string text		=	GetText(val2);
				PaintText(g, bounds, text, alignToRight,rowNum,selectedRow,dgSelectedRow);
			}
			catch
			{}
		}

		// Helper functions
		private void PaintText(Graphics g ,Rectangle bounds, string text,bool alignToRight,int rowNum,bool selectedRow,bool dgSelectedRow) 
		{
			Brush backBrush			=	null;
			Brush foreBrush			=	null;

			if ( selectedRow && dgSelectedRow )
			{
				backBrush			=	new SolidBrush(this.DataGridTableStyle.SelectionBackColor);
				foreBrush			=	new SolidBrush(this.DataGridTableStyle.SelectionForeColor);
			}
			else
			{
				if ( ReadOnly && selectedRow && ( _dataGrid.CurrentCell.ColumnNumber == this.DataGridTableStyle.GridColumnStyles.IndexOf(this)) )
					backBrush		=	new SolidBrush(System.Drawing.Color.LightGray);
				else if ( rowNum % 2 == 0 )
					backBrush	=	new SolidBrush(this.DataGridTableStyle.BackColor);
				else	backBrush	=	new SolidBrush(this.DataGridTableStyle.AlternatingBackColor);
				foreBrush			=	new SolidBrush(this.DataGridTableStyle.ForeColor);
			}
			Rectangle rect			=	bounds;
			RectangleF rectF		=	rect; 
			StringFormat format		=	new StringFormat();
			if( alignToRight ) 
			{
				format.FormatFlags	=	StringFormatFlags.DirectionRightToLeft;
			}
			switch( this.Alignment ) 
			{
				case HorizontalAlignment.Left:
					format.Alignment	=	StringAlignment.Near;
					break;
				case HorizontalAlignment.Right:
					format.Alignment	=	StringAlignment.Far;
					break;
				case HorizontalAlignment.Center:
					format.Alignment	=	StringAlignment.Center;
					break;
			}
			format.FormatFlags	=	StringFormatFlags.NoWrap;
			g.FillRectangle(backBrush, rect);
			rectF.Offset(0, _yMargin);
			rectF.Height		-=	_yMargin;
			g.DrawString(text, this.DataGridTableStyle.DataGrid.Font, foreBrush, rectF, format);
			format.Dispose();
		}

		private string GetText(object val) 
		{
			//return _dateTimePicker.Text;
			if ( val is DateTime )
				return ((DateTime)val).ToShortDateString();
			return val.ToString();
		}
	}

}
